package com.flca.frw.util
{
	import mx.rpc.Fault;
	import mx.utils.StringUtil;
	
	import com.flca.frw.model.ExceptionInfo;
	import com.flca.frw.model.ExceptionDetailInfo;
	
	public class ExceptionUtil 
	{
		public static function isApplicationException(aFault:Fault):Boolean
		{
			var result:Boolean;
			
			result = aFault.faultDetail != null && aFault.faultDetail.indexOf("codedExceptionInfos") >= 0;
			
			return result;
		}
		public static function parseFault(aFault:Fault):ExceptionInfo
		{
			var xmlString:String;
			var index:int;
			var xml:XML;
			var details:Array;
			var detailArgs:Array;
			var result:ExceptionInfo;
			
			try
			{
				index = aFault.faultDetail.indexOf(" ");
				xmlString = aFault.faultDetail.substring(0, index) 
				            + ' xmlns:xsi="bla"' 
				            + aFault.faultDetail.substring(index);
				            
				xml = new XML(xmlString);
				
				details = new Array();
				for each (var detailXml:XML in xml.codedExceptionInfos.codedExceptionInfos) 
				{
					detailArgs = new Array();
					
					for each (var detailArgsXml:XML in detailXml.args.args)
					{
						detailArgs.push(detailArgsXml.toString());
					}
					
					details.push(new ExceptionDetailInfo(detailXml.code, detailArgs));
				}

				result = new ExceptionInfo(xml.logId, xml.message, details);
			}
			catch (error:Error)
			{
				result = new ExceptionInfo('unknown', aFault.faultString);
			}
			
			return result;
		}
		
		public static function translateExceptionInfo(aInfo:ExceptionInfo, aXml:XML):String
		{
			var infoDetail:ExceptionDetailInfo;
			var pattern:String;
			var result:String;

			result = "";
				
			if (aInfo != null && aInfo.details != null)
			{
				for (var m:int = 0; m < aInfo.details.length; m ++) 
				{
					infoDetail = aInfo.details[m] as ExceptionDetailInfo;
					
					pattern = null;
					for (var i:int = 0; i < aXml.message.length(); i ++) 
					{
					    if (aXml.message[i].attribute("code") == infoDetail.code) 
					    {
					        pattern = aXml.message[i].attribute("pattern");
					        break;
					    } 
					}
					
					if (pattern != null)
					{
						if (result.length != 0)
						{
							result += "\n\n";
						}
						
						result += StringUtil.substitute(pattern, infoDetail.args);
					}
				}
			}
			
			if (result == "")
			{
				result = "unknown message '" + aInfo + "' received.";
			}
			
			return result;
		}
		
		public static function determineIfCodeIsPresent(aInfo:ExceptionInfo, aCode:String):Boolean
		{
			var infoDetail:ExceptionDetailInfo;
			var result:Boolean;
			
			result = false;
			
			if (aCode != null && aInfo != null && aInfo.details != null)
			{
				for (var m:int = 0; m < aInfo.details.length; m ++) 
				{
					infoDetail = aInfo.details[m] as ExceptionDetailInfo;
					if (aCode == infoDetail.code)
					{
						result = true;
						break;
					}
				}
			}
			
			return result;
		}
	}
}